#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
时间调度模块
"""

import threading
import time
from datetime import datetime, timedelta
import sqlite3
from config import DATABASE_PATH

class BellScheduler:
    def __init__(self):
        """初始化调度器"""
        self.is_running = False
        self.schedule_thread = None
        self.bell_times = []  # 存储铃声时间点
        self.skipped_bell = None  # 存储被跳过的铃声时间点
        self.current_weekday_plan_id = None  # 当前星期几的方案ID
        self.on_bell_trigger = None  # 铃声触发回调函数
        self.load_schedule()
    
    def set_bell_trigger_callback(self, callback):
        """
        设置铃声触发回调函数
        
        Args:
            callback (function): 回调函数，接受audio_file和volume两个参数
        """
        self.on_bell_trigger = callback
    
    def set_weekday_plan(self, plan_id):
        """
        设置当前星期几的方案
        
        Args:
            plan_id (int): 方案ID
        """
        self.current_weekday_plan_id = plan_id
        self.load_schedule()
    
    def load_schedule(self):
        """从数据库加载方案"""
        try:
            conn = sqlite3.connect(DATABASE_PATH)
            cursor = conn.cursor()
            
            # 如果设置了星期方案，则只加载该方案的铃声时间点
            if self.current_weekday_plan_id is not None:
                cursor.execute("""
                    SELECT bt.time, bt.audio_file, bt.volume, p.type
                    FROM bell_time bt
                    JOIN plan p ON bt.plan_id = p.id
                    WHERE bt.plan_id = ? AND p.is_active = 1
                    ORDER BY bt.time
                """, (self.current_weekday_plan_id,))
            else:
                # 查询启用的方案中的铃声时间点
                cursor.execute("""
                    SELECT bt.time, bt.audio_file, bt.volume, p.type
                    FROM bell_time bt
                    JOIN plan p ON bt.plan_id = p.id
                    WHERE p.is_active = 1
                    ORDER BY bt.time
                """)
            
            self.bell_times = cursor.fetchall()
            conn.close()
            return True
        except Exception as e:
            print(f"加载方案时出错: {e}")
            return False
    
    def add_bell_time(self, bell_time, audio_file, volume=80):
        """
        添加铃声时间点
        
        Args:
            bell_time (str): 铃声时间(HH:MM:SS格式)
            audio_file (str): 音频文件路径
            volume (int): 音量大小(0-100)
        """
        self.bell_times.append((bell_time, audio_file, volume, "default"))
    
    def remove_bell_time(self, bell_time):
        """
        移除铃声时间点
        
        Args:
            bell_time (str): 铃声时间(HH:MM:SS格式)
        """
        self.bell_times = [bt for bt in self.bell_times if bt[0] != bell_time]
    
    def get_next_bell_time(self):
        """获取下一个铃声时间"""
        if not self.bell_times:
            return None
        
        now = datetime.now().time()
        for bell_time_str, audio_file, volume, plan_type in self.bell_times:
            bell_time = datetime.strptime(bell_time_str, "%H:%M:%S").time()
            if bell_time > now:
                # 如果这个铃声被跳过了，继续查找下一个
                if bell_time_str == self.skipped_bell:
                    continue
                # 返回时间、铃声文件和音量信息
                return {
                    'time': bell_time_str,
                    'audio_file': audio_file,
                    'volume': volume,
                    'plan_type': plan_type
                }
        # 如果今天没有更多铃声，返回明天第一个
        for bell_time_str, audio_file, volume, plan_type in self.bell_times:
            if bell_time_str != self.skipped_bell:
                return {
                    'time': bell_time_str,
                    'audio_file': audio_file,
                    'volume': volume,
                    'plan_type': plan_type
                }
        return None
    
    def skip_next_bell(self):
        """跳过下次铃声"""
        next_bell = self.get_next_bell_time()
        if next_bell:
            self.skipped_bell = next_bell['time']  # 只存储时间字符串
            return next_bell
        return None
    
    def clear_skipped_bell(self):
        """清除跳过的铃声标记"""
        self.skipped_bell = None
    
    def start_scheduler(self):
        """启动调度器"""
        if self.is_running:
            return
        
        self.is_running = True
        self.schedule_thread = threading.Thread(target=self._schedule_loop)
        self.schedule_thread.daemon = True
        self.schedule_thread.start()
        print("铃声调度器已启动")
    
    def stop_scheduler(self):
        """停止调度器"""
        self.is_running = False
        if self.schedule_thread:
            self.schedule_thread.join()
        print("铃声调度器已停止")
    
    def _schedule_loop(self):
        """调度循环"""
        while self.is_running:
            now = datetime.now()
            current_time_str = now.strftime("%H:%M:%S")
            
            # 检查是否有铃声需要播放
            for bell_time_str, audio_file, volume, _ in self.bell_times:
                # 如果这个铃声被跳过了，不播放
                if bell_time_str == self.skipped_bell:
                    continue
                if bell_time_str == current_time_str:
                    # 触发铃声播放事件
                    self._trigger_bell(audio_file, volume)
                    # 播放后清除跳过标记
                    self.clear_skipped_bell()
            
            # 每秒检查一次
            time.sleep(1)
    
    def _trigger_bell(self, audio_file, volume):
        """
        触发铃声播放（需要在主程序中实现具体的播放逻辑）
        
        Args:
            audio_file (str): 音频文件路径
            volume (int): 音量大小
        """
        print(f"触发铃声播放: {audio_file} (音量: {volume})")
        # 这里应该调用音频播放模块
        # 由于模块间解耦，实际播放逻辑在主程序中实现
        # 发送事件通知主程序播放铃声
        if self.on_bell_trigger is not None:
            self.on_bell_trigger(audio_file, volume)

def main():
    # 测试代码
    scheduler = BellScheduler()
    print("时间调度模块测试")
    
if __name__ == "__main__":
    main()